const express = require('express');
const cors = require('cors');
const fetch = require('node-fetch');
const bodyParser = require('body-parser');
require('dotenv').config();
// 创建Express应用
const app = express();
const PORT = process.env.PORT || 3000;
// 配置CORS中间件，只允许特定域名访问
const corsOptions = {
  origin: 'https://rsjsq.aiqji.com', // 替换为您实际的域名
  methods: ['GET', 'POST'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-Id'],
  credentials: true,
  optionsSuccessStatus: 200 // 一些旧浏览器(IE11, various SmartTVs)会对204状态码有问题
};
// 中间件
app.use(cors(corsOptions));
app.use(bodyParser.json()); // 解析JSON请求体
// 请求日志中间件
app.use((req, res, next) => {
  console.log(`${new Date().toISOString()} - ${req.method} ${req.url} - IP: ${req.ip}`);
  next();
});
// 添加一个简单的锁机制防止并发请求
const requestLocks = new Map();
// 测试连接端点
app.get('/api/test', (req, res) => {
  res.json({ status: 'ok', message: '后端连接正常' });
});
// 添加请求计数器
const requestCounter = {
  total: 0,
  description: 0,
  yiyan: 0
};
// 添加中间件来计数请求
app.use((req, res, next) => {
  requestCounter.total = (requestCounter.total || 0) + 1;

  if (req.path === '/api/generate-description') {
    requestCounter.description = (requestCounter.description || 0) + 1;
  } else if (req.path === '/api/yiyan') {
    requestCounter.yiyan = (requestCounter.yiyan || 0) + 1;
  }
  next();
});
// 生命阶段描述API
app.post('/api/generate-description', async (req, res) => {
  console.log('收到生成描述请求:', req.body);
  const { age, stage, birthYear, lifeExpectancy } = req.body;

  if (!age || !stage) {
    return res.status(400).json({
      error: '缺少必要参数'
    });
  }
  // 创建请求ID
  const requestId = req.headers['x-request-id'] || Date.now().toString();
  console.log(`处理请求ID: ${requestId}`);
  // 检查该请求ID是否有请求正在处理
  if (requestLocks.has(requestId)) {
    return res.status(429).json({
      error: '已有一个请求正在处理中，请等待当前请求完成'
    });
  }
  // 设置锁
  requestLocks.set(requestId, true);
  // 设置流式响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');
  res.setHeader('X-Accel-Buffering', 'no'); // 禁用Nginx缓冲
  res.setHeader('Transfer-Encoding', 'chunked'); // 使用分块传输编码
  let deltaStructureLogged = false;
  try {
    // 构建请求体
    const requestBody = {
      model: 'deepseek-reasoner',
      messages: [{
        role: 'user',
        content: `请以温暖、富有哲理的口吻，描述一个${age}岁（${stage}）的人生阶段。这个人出生于${birthYear}年，预期寿命${lifeExpectancy}岁。
        描述应该包含这个年龄段的特点、可能经历的事情、面临的机遇与挑战，以及一些积极的建议和理解。
        要有美感。在最后加上一个表情符号，来结束这个输出。切记不要有短掉的句子。
        字数控制在200字左右，然后再加一个随机鼓励的英文单词，饱含诗意，最好再做一个简单的以后的规划。
        整体要简洁儒雅。`
      }],
      temperature: 0.7,
      max_tokens: 500,
      stream: true
    };
    console.log('向DeepSeek发送请求...');
    // 发送请求到DeepSeek API
    const apiResponse = await fetch('https://api.deepseek.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}`,
        'Accept': 'application/json'
      },
      body: JSON.stringify(requestBody)
    });
    if (!apiResponse.ok) {
      const errorData = await apiResponse.json();
      console.error('API请求失败:', errorData);
      // 使用预设描述
      const fallbackDescription = getFallbackDescription(stage);
      simulateStreamResponse(fallbackDescription, res, requestId);
      return;
    }
    // 处理流式响应
    const reader = apiResponse.body;
    let buffer = '';
    let lastChunkTime = Date.now();
    // 处理流式响应
    reader.on('data', chunk => {
      try {
        const text = chunk.toString();
        buffer += text;
        // 处理可能的多行数据
        const lines = buffer.split('\n\n');
        // 保留最后一个可能不完整的行
        buffer = lines.pop() || '';
        for (const line of lines) {
          const trimmedLine = line.trim();
          if (!trimmedLine || !trimmedLine.startsWith('data:')) continue;
          const data = trimmedLine.substring(5).trim();
          // 处理[DONE]标记
          if (data === '[DONE]') {
            console.log('收到流结束标记');
            res.write('data: [DONE]\n\n');
            if (res.flush) res.flush(); // 确保立即发送
            continue;
          }
          // 2. 修改解析响应部分，处理reasoning_content
          try {
            const parsedData = JSON.parse(data);
            // 提取内容
            if (parsedData.choices &&
              parsedData.choices[0] &&
              parsedData.choices[0].delta) {
              // 记录第一个响应的完整结构
              if (!deltaStructureLogged) {
                console.log("首个Delta完整结构:", JSON.stringify(parsedData));
                deltaStructureLogged = true;
              }
              // 添加这一行：正确定义delta变量
              const delta = parsedData.choices[0].delta;
              // 处理常规content
              if (delta.content) {
                // 获取内容
                const content = delta.content;
                // 将内容进一步细分为更小的块，增强流式效果
                const now = Date.now();
                const timeSinceLastChunk = now - lastChunkTime;
                // 如果自上一个块以来的时间太短，则强制添加延迟
                if (timeSinceLastChunk < 30 && content.length > 1) {
                  // 进一步分割成小块
                  const microChunks = [];
                  for (let i = 0; i < content.length; i++) {
                    microChunks.push(content.charAt(i));
                  }
                  // 循环发送每个微小块，添加小延迟
                  let i = 0;
                  const sendNextMicroChunk = () => {
                    if (i < microChunks.length) {
                      const microChunk = microChunks[i];
                      console.log(`发送微块[${i + 1}/${microChunks.length}]: "${microChunk}"`);
                      res.write(`data: {"chunk": ${JSON.stringify(microChunk)}}\n\n`);
                      if (res.flush) res.flush(); // 确保立即发送
                      i++;
                      setTimeout(sendNextMicroChunk, 20); // 每20ms发送一个字符
                    }
                  };
                  sendNextMicroChunk();
                } else {
                  // 直接发送内容
                  console.log(`发送内容块: "${content.substring(0, 20)}${content.length > 20 ? '...' : ''}", 长度: ${content.length}`);
                  res.write(`data: {"chunk": ${JSON.stringify(content)}}\n\n`);
                  if (res.flush) res.flush(); // 确保立即发送
                }
                lastChunkTime = now;
              }
              // 新增: 处理reasoning_content
              if (delta.reasoning_content) {
                const reasoningContent = delta.reasoning_content;
                console.log(`发送思维链内容: "${reasoningContent.substring(0, 20)}${reasoningContent.length > 20 ? '...' : ''}", 长度: ${reasoningContent.length}`);
                // 使用特殊字段标识思维链内容
                res.write(`data: {"reasoning_chunk": ${JSON.stringify(reasoningContent)}}\n\n`);
                if (res.flush) res.flush(); // 确保立即发送
                // 更新lastChunkTime，因为思维链内容不应影响主内容的流式效果
                lastChunkTime = Date.now();
              }
            }
          } catch (parseError) {
            console.error('解析JSON数据出错:', parseError, data.substring(0, 100));
          }
        }
      } catch (err) {
        console.error('处理数据块出错:', err);
      }
    });
    reader.on('end', () => {
      console.log('DeepSeek流结束');
      res.write('data: [DONE]\n\n');
      if (res.flush) res.flush();
      res.end();
      requestLocks.delete(requestId);
    });
    reader.on('error', (err) => {
      console.error('DeepSeek流错误:', err);
      res.write(`data: {"error": ${JSON.stringify(err.message)}}\n\n`);
      res.write('data: [DONE]\n\n');
      if (res.flush) res.flush();
      res.end();
      requestLocks.delete(requestId);
    });
  } catch (error) {
    console.error('处理请求时出错:', error);
    res.write(`data: {"error": ${JSON.stringify(error.message)}}\n\n`);
    res.write('data: [DONE]\n\n');
    if (res.flush) res.flush();
    res.end();
    requestLocks.delete(requestId);
  }
});
// 修改后的模拟流式响应函数
function simulateStreamResponse(text, res, requestId) {
  console.log('开始模拟流式响应，总字符数:', text.length);
  const chunks = [];
  // 将文本分成小块，每块1-2个字符，模拟真实流式响应
  for (let i = 0; i < text.length;) {
    const chunkSize = Math.floor(Math.random() * 2) + 1; // 1-2个字符
    chunks.push(text.substring(i, Math.min(i + chunkSize, text.length)));
    i += chunkSize;
  }
  console.log(`将文本分成了${chunks.length}个小块`);
  // 生成一些模拟的思维链内容
  const reasoningSteps = [
    "我需要描述这个人生阶段的特点...",
    "这个年龄段可能会经历什么...",
    "面临的机遇和挑战包括...",
    "我应该给出一些积极的建议...",
    "文字需要保持温暖、哲理的风格..."
  ];
  // 记录已发送的思维链步骤
  let reasoningIndex = 0;
  // 发送小块
  let index = 0;
  const intervalId = setInterval(() => {
    if (index >= chunks.length) {
      clearInterval(intervalId);
      console.log('模拟流式响应完成');
      res.write('data: [DONE]\n\n');
      if (res.flush) res.flush();
      res.end();
      // 释放锁
      requestLocks.delete(requestId);
      return;
    }
    // 使用JSON.stringify确保特殊字符被正确处理
    const chunk = chunks[index];
    console.log(`发送块[${index + 1}/${chunks.length}]: "${chunk}"`);
    res.write(`data: {"chunk": ${JSON.stringify(chunk)}}\n\n`);
    // 每发送约20%的内容块，发送一段思维链内容
    if (reasoningIndex < reasoningSteps.length && index % Math.floor(chunks.length / reasoningSteps.length) === 0) {
      console.log(`发送模拟思维链: "${reasoningSteps[reasoningIndex]}"`);
      res.write(`data: {"reasoning_chunk": ${JSON.stringify(reasoningSteps[reasoningIndex])}}\n\n`);
      reasoningIndex++;
    }
    if (res.flush) res.flush(); // 确保立即发送
    index++;
  }, 80); // 增加到80毫秒，让效果更明显
}
// 提供预设描述的辅助函数
function getFallbackDescription(stage) {
  const descriptions = {
    '婴儿期': '　　这是人生最初的启程，一个充满好奇和探索的时期。在这个阶段，每一天都在学习最基本的生存技能，从咿呀学语到蹒跚学步，每一个进步都令人欣喜。世界对你来说是全新的画布，而你正在用自己的方式描绘第一笔。父母的爱是你的港湾，他们的每一个微笑和鼓励都是你勇敢探索的动力。享受这纯真无邪的美好时光，因为它将成为你人生旅程中最珍贵的开端。🌱',
    '幼儿期': '　　想象力和创造力开始绽放的黄金时期。你的世界充满了无限可能，每一天都是新奇冒险的开始。通过游戏和互动，你不仅认识这个世界，还在建立最初的社交关系，形成基本的性格特征。这个时期的经历会深刻影响你未来的发展方向。父母和教育者的引导尤为重要，既要给予足够的自由空间发展创造力，又要适当设立界限培养规则意识。珍惜这段时光，它是构建未来的重要基石。✨',
    '童年期': '　　求知欲旺盛的美好时光，这是你系统接受教育的开始，也是培养兴趣爱好的关键期。友谊在这个阶段变得格外珍贵，同伴之间的互动教会你分享、合作与理解。纯真的快乐和无忧无虑是这个阶段的特权，同时也在为未来的成长打下重要基础。好奇心是你最大的财富，保护它、培养它，让它引导你探索这个奇妙的世界。家长和老师的鼓励与引导，将帮助你建立自信和良好的学习习惯。🌈',
    '青少年期': '　　充满活力与梦想的转变期，你的身心正在快速发展，观念和价值观开始形成。这是开始思考人生方向，建立自我认知的重要阶段，同时也面临着升学和未来规划的挑战。叛逆与困惑或许会时常造访，但这恰是你寻找自我、确立独立思想的必经之路。友谊和同辈关系在此时变得尤为重要，它们塑造着你的社交视野。不要害怕犯错，因为每一次跌倒都是成长的契机。相信自己，你正在成为独一无二的存在。🌟',
    '成年早期': '　　迈入独立生活的重要阶段，你或许正面临学业深造或职业选择的关键决策。这是建立社会关系网络、逐步承担责任、规划人生方向的时期。初入社会的挑战与机遇并存，每一次尝试都在丰富你的阅历。不要对自己期望过高，成长需要时间，成功需要积累。保持开放的心态去学习和适应，同时也要倾听内心的声音，找到真正适合自己的道路。记住，这是探索的时期，尝试不同可能性是完全正常的。💫',
    '青年期': '　　事业发展的黄金时期，你在工作中积累经验，专业能力日益成熟。同时，这也可能是你开始组建家庭的阶段，学习平衡事业与生活的艺术。责任感和使命感逐渐增强，你的决策开始影响更多人的生活。面对压力和挑战时，学会自我调适和寻求支持。不要忽视个人成长和情感需求，工作成就之外，内心的富足同样重要。努力工作，但也请记得，生活的意义不仅在于成就，还在于那些与所爱之人共度的温暖时光。🌻',
    '中年早期': '　　事业和家庭逐渐稳定的时期，你在工作中可能已达到较高水平，同时面临家庭教育等多重责任。这是人生的重要承上启下阶段，既要照顾上一代，又要培养下一代。在享受成就的同时，也可能开始思考人生的意义和价值。保持学习的热情和开放的心态，不断更新自己的知识和技能。照顾好自己的身心健康，为长远的人生做好准备。学会适时放慢脚步，欣赏沿途的风景，体会生活的细腻与丰富。🍁',
    '中年期': '　　经验和智慧日益丰富的阶段，你可能在工作中处于领导岗位，拥有丰富的人生阅历和专业技能。家庭生活趋于成熟，与伴侣的关系更加稳定深厚。这是开始思考人生更深层意义的时期，价值观可能会有所调整和升华。身体状况的变化提醒你更加关注健康，建立良好的生活习惯。不妨尝试一些新的兴趣爱好，发掘自己未曾展现的才能。传递经验给年轻一代，帮助他们少走弯路，也能带给你成就感和意义感。🌲',
    '老年期': '　　收获人生智慧的时期，你可以放慢脚步享受生活，陪伴家人，培养兴趣爱好。这是回顾、总结和回馈的阶段，你的经验和智慧是年轻一代的宝贵财富。保持积极的心态和健康的生活方式尤为重要，它们能帮助你更好地享受这段时光。与家人朋友保持紧密联系，分享你的故事和智慧。尝试新事物，保持好奇心和学习欲望，年龄从不是障碍。每一天都是礼物，怀着感恩之心，平静安详地享受人生的这一阶段。🌅'
  };
  return descriptions[stage] || '　　这是人生的重要阶段，每个时期都有其独特的意义和价值。经历是我们成长的养分，挑战是我们前进的动力。无论这一阶段带来什么，都以开放的心态接纳，从中汲取智慧与力量。生命的旅程充满惊喜，愿你在每个阶段都能找到属于自己的意义与美好。✨';
}
// 简化的一言系统 - 只使用内置数据
const yiyanCollection = {
  quotes: [
    '🌿 天行健，君子以自强不息 ——《周易》',
    '🌼 宠辱不惊，闲看庭前花开花落 ——《幽窗小记》',
    '🌊 不积跬步，无以至千里 —— 荀子',
    '✨ 万物皆有裂痕，那是光之来处 —— 莱昂纳德·科恩',
    '🦋 当你真心渴望，宇宙自会回应 ——《牧羊少年》',
    '🌙 行到水穷处，坐看云起时 —— 王维',
    '⚡ 每个不曾起舞的日子都是对生命的辜负 —— 尼采',
    '🍃 盛年不重来，一日难再晨 —— 陶渊明',
    '🌠 所谓无底深渊，下去便是前程万里 —— 木心',
    '🤝 莫愁前路无知己，天下谁人不识君 —— 高适',
    '💡 真正的英雄是认清生活后依然热爱 —— 罗曼·罗兰',
    '⛰️ 你生而有翼，何必匍匐前行 —— 鲁米',
    '🌸 没有风暴的海洋只是泥塘 —— 余世存',
    '🌌 人生如逆旅，我亦是行人 —— 苏轼'
  ],
  getRandomQuote() {
    return this.quotes[Math.floor(Math.random() * this.quotes.length)];
  }
};
// IP限流系统，限制单个IP的请求频率
const yiyanRateLimits = new Map(); // IP地址 -> 上次请求时间
// 简化的一言获取接口 - 仅使用内置数据
app.get('/api/yiyan', (req, res) => {
  console.log('收到一言请求');
  const clientIP = req.ip;
  const now = Date.now();
  const lastRequestTime = yiyanRateLimits.get(clientIP) || 0;
  // IP频率限制 - 5秒内不允许同一IP重复请求
  if (now - lastRequestTime < 5000) {
    console.log(`IP ${clientIP} 请求过于频繁，返回随机数据`);
    return res.json({
      code: 200,
      msg: yiyanCollection.getRandomQuote()
    });
  }
  // 记录本次请求时间
  yiyanRateLimits.set(clientIP, now);
  // 返回随机一言
  const quote = yiyanCollection.getRandomQuote();
  console.log('返回一言:', quote);
  res.json({
    code: 200,
    msg: quote
  });
});
// 服务状态API
app.get('/api/status', (req, res) => {
  const serverInfo = {
    status: 'online',
    uptime: process.uptime(),
    startTime: new Date(Date.now() - process.uptime() * 1000).toISOString(),
    memory: process.memoryUsage(),
    requests: requestCounter,
    apiKeys: {
      deepseek: process.env.DEEPSEEK_API_KEY ? 'configured' : 'missing'
    },
    version: '1.0.0'
  };
  res.json(serverInfo);
});
// 在app.listen中更新API检查
app.listen(PORT, '0.0.0.0', () => {
  console.log(`
====================================
后端服务启动信息:
- 时间: ${new Date().toISOString()}
- 端口: ${PORT}
- 环境: ${process.env.NODE_ENV || 'development'}
- Node版本: ${process.version}
- 平台: ${process.platform}
- 内存使用: ${Math.round(process.memoryUsage().heapUsed / 1024 / 1024)} MB
- DEEPSEEK API密钥: ${process.env.DEEPSEEK_API_KEY ? '已设置' : '未设置'}
====================================
  `);
});